<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>My first three.js app</title>
		<style>
			body { margin: 0; }
		</style>
	</head>
	<body>
		<script type="module">
			import * as THREE from 'https://unpkg.com/three/build/three.module.js';
			// Our Javascript will go here.

// 建立场景、相机和渲染器

      const scene = new THREE.Scene();
    // erspectiveCamera（透视摄像机）
      // 第一个参数是视野角度（FOV）。视野角度就是无论在什么时候，你所能在显示器上看到的场景的范围，它的单位是角度(与弧度区分开)。
      // 第二个参数是长宽比（aspect ratio）。 也就是你用一个物体的宽除以它的高的值。比如说，当你在一个宽屏电视上播放老电影时，可以看到图像仿佛是被压扁的。
      // 接下来的两个参数是近截面（near）和远截面（far）。 当物体某些部分比摄像机的远截面远或者比近截面近的时候，该这些部分将不会被渲染到场景中。或许现在你不用担心这个值的影响，但未来为了获得更好的渲染性能，你将可以在你的应用程序里去设置它。
      const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );

      // 渲染器WebGLRenderer
      const renderer = new THREE.WebGLRenderer();

      // 在应用程序里设置染器的尺寸，将场景渲染填充
      // 可以将渲染器宽高设置为浏览器窗口宽高。
      // 使用setSize传入一个较小的值，例如window.innerWidth/2和window.innerHeight/2，这将使得应用程序在渲染时，以一半的长宽尺寸渲染场景。
      // 如果想保持应用程序的尺寸，但是以较低的分辨率来渲染，在调用setSize时，将updateStyle（第三个参数）设为false。例如，假设你的<canvas> 标签现在已经具有了100%的宽和高，调用setSize(window.innerWidth/2, window.innerHeight/2, false)将使得你的应用程序以一半的分辨率来进行渲染。

// 最后，将renderer（渲染器）的dom元素（renderer.domElement）添加到我们的HTML文档中。就是渲染器用来显示场景给我们看的<canvas>元素。
      renderer.setSize( window.innerWidth, window.innerHeight );
      document.body.appendChild( renderer.domElement );


//添加立方体
      const geometry = new THREE.BoxGeometry( 1, 1, 1 );
        // 设置一个color属性，值为0x00ff00；这里所做的事情，和在CSS或者Photoshop中使用十六进制(hex colors)颜色格式来设置颜色的方式一致。
      const material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
      const cube = new THREE.Mesh( geometry, material );
      scene.add( cube );

      camera.position.z = 5;

      //1.BoxGeometry（立方体）对象：包含了一个立方体中所有的顶点（vertices）和面（faces）。
      // 2.给材质，让它有颜色。Three.js自带了几种材质，如：MeshBasicMaterial。
        // 所有的材质都存有应用于他们的属性的对象。
      // 3.需要一个Mesh（网格）。 包含一个几何体以及作用在此几何体上的材质，我们可以直接将网格对象放入到我们的场景中，并让它在场景中自由移动。
        // 默认情况下，当调用scene.add()的时候，物体将会被添加到(0,0,0)坐标。但将使得摄像机和立方体彼此在一起。
        //为了防止这种情况的发生，我们只需要将摄像机稍微向外移动一些即可。


// 渲染场景
        // “渲染循环”（render loop）或 “动画循环”（animate loop）

        function animate() {
          requestAnimationFrame( animate );
          renderer.render( scene, camera );
        }
        animate();
        // 在这里我们创建了一个使渲染器能够在每次屏幕刷新时对场景进行绘制的循环（在大多数屏幕上，刷新率一般是60次/秒）。
        // 当然可以用setInterval实现刷新的功能;
        // requestAnimationFrame有很多的优点。最重要的一点或许就是当用户切换到其它的标签页时，它会暂停，因此不会浪费用户宝贵的处理器资源，也不会损耗电池的使用寿命。

//使立方体动起来
        // 在开始之前，如果你已经将上面的代码写入到了你所创建的文件中，你可以看到一个绿色的方块。

        // 将下列代码添加到animate()函数中renderer.render调用的上方：

        cube.rotation.x += 0.01;
        cube.rotation.y += 0.01;
// 这段代码每帧都会执行（正常情况下是60次/秒），这就让立方体有了一个看起来很不错的旋转动画。
// 基本上来说，当应用程序运行时，如果你想要移动或者改变任何场景中的东西，都必须要经过这个动画循环。当然，你可以在这个动画循环里调用别的函数，这样你就不会写出有上百行代码的animate函数。



		</script>
	</body>
</html>